﻿using Facebook;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Web;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.StorageClient;
using Microsoft.WindowsAzure.ServiceRuntime;


namespace Hangout.Web.Core.Accounts
{
    public class User
    {



        public static UserData? RegisterUser(string accessToken,ref Model.HangoutDBEntities context)
        {
            try
            {

                //if user is registered then update the details else create a new user

                FacebookClient client = new FacebookClient(accessToken);

                string result = client.Get("me").ToString();



                JObject obj = JObject.Parse(result);

                string name = "", link = "", username = "", email = "", relationshipStatus = "",firstname="",lastname="";
                long id = -1;
                float timezone = 0.0f;
                bool? gender=null;
                DateTime? dob = null;

                if (obj.SelectToken("id") != null)
                {
                    id = long.Parse(obj.SelectToken("id").ToString());
                }
                else
                {
                    return new UserData();
                }
                

                Model.User user;
                bool newuser = false,newProfile=false;;

                if (DoesUserExists(id, ref context))
                {
                    user = GetUser(id, ref context);
                }
                else
                {
                    user = new Model.User();
                    newuser = true;
                }



                if (obj.SelectToken("name") != null)
                {
                    name = obj.SelectToken("name").ToString();
                }

                if (obj.SelectToken("id") != null)
                {
                    id = long.Parse(obj.SelectToken("id").ToString());
                }

                if (obj.SelectToken("link") != null)
                {
                    link = obj.SelectToken("link").ToString();
                }

                if (obj.SelectToken("username") != null)
                {
                    username = obj.SelectToken("username").ToString();
                }


                if (obj.SelectToken("email") != null)
                {
                    email = obj.SelectToken("email").ToString();
                }

                if (obj.SelectToken("relationship_status") != null)
                {
                    relationshipStatus = obj.SelectToken("relationship_status").ToString();
                    if(relationshipStatus!="In a relationship"&&relationshipStatus!="Married"&&relationshipStatus!="Engaged")
                    {
                        relationshipStatus = "Single";
                    }
                }
                else
                {
                    relationshipStatus = "Single"; //Default it to single :)
                }

                if (obj.SelectToken("timezone") != null)
                {
                    timezone = float.Parse(obj.SelectToken("timezone").ToString());
                }

                if (obj.SelectToken("first_name") != null)
                {
                    firstname = obj.SelectToken("first_name").ToString();
                }

                if (obj.SelectToken("last_name") != null)
                {
                    lastname = obj.SelectToken("last_name").ToString();
                }

                if (obj.SelectToken("birthday_date") != null)
                {
                    dob = DateTime.Parse(obj.SelectToken("birthday_date").ToString());
                }

                
                if (obj.SelectToken("gender") != null)
                {
                    string tmp = obj.SelectToken("gender").ToString();
                    if(tmp=="male")
                    {
                        gender=true;
                    }
                    else if (tmp=="female")
                    {
                        gender=false;
                    }
                    else
                    {
                        gender=null;
                    }


                }

                user.AccessToken = accessToken;
                user.Activated = true;
                user.Blocked = false;
                user.DateTimeStamp = DateTime.Now;
                user.DateTimeUpdated = DateTime.Now;
                user.Email = email;
                user.Expires = DateTime.Now.AddDays(120);
                user.FacebookUserID = id;
                user.Username = username;

                
                //create a user profile
                Model.UserProfile profile=null;


                if (newuser)
                {
                    profile = new Model.UserProfile();
                    newProfile = true;
                    context.Users.AddObject(user);

                }
                else
                {
                    if (user.UserID!=0)
                    {
                        profile = GetUserProfile(user.UserID,context);
                    }
                    if (profile == null)
                    {
                        newProfile = true;
                        profile = new Model.UserProfile();
                    }
                    
                }

                profile.User = user;
                profile.Name = name;
                profile.Link = link;
                profile.RelationshipStatus = relationshipStatus;
                profile.Timezone = timezone;
                profile.DateTimeStamp = DateTime.Now;
                profile.DateTimeUpdated = DateTime.Now;
                profile.Gender = gender;
                profile.FirstName = firstname;
                profile.LastName = lastname;

                if (dob != null)
                {
                    profile.Birthday = dob;
                }

                if (profile.Birthday != null)
                {
                    profile.Age=DateTime.Now.Year-((DateTime)(profile.Birthday)).Year;
                }

                if (newProfile)
                {
                    context.AddToUserProfiles(profile);
                }

                WebRequest request = WebRequest.Create(string.Format("https://graph.facebook.com/{0}/picture", user.FacebookUserID));
                WebResponse response = request.GetResponse();
                string pictureUrl = response.ResponseUri.ToString();

                request = WebRequest.Create(string.Format("https://graph.facebook.com/{0}/picture?type=large", user.FacebookUserID));
                response = request.GetResponse();
                string largepictureUrl = response.ResponseUri.ToString();

                profile.ProfilePicURL = pictureUrl;
                profile.LargeProfilePicURL = largepictureUrl;

                context.SaveChanges();

                Core.Cloud.Queue.RefreshFacebookLikes(user.UserID);
                

                return new UserData { Profile=GetUserProfile(profile.UserID,context),User=GetUser(user.UserID,ref context) };
            }
            catch(Exception e)
            {
                Debug.WriteLine(e.Message);
                return null;

            }


        }

        public static Model.UserProfile GetUserProfile(int userId,Model.HangoutDBEntities context)
        {
            return context.UserProfiles.SingleOrDefault(o => o.UserID == userId);
        }

        public  static bool DoesUserExists(long facebookId,ref Model.HangoutDBEntities context)
        {
            if (context.Users.SingleOrDefault(o => o.FacebookUserID == facebookId) == null)
            {
                return false;
            }

            return true;
        }

        public static bool ValidateUser(long userId, string accesstoken,ref Model.HangoutDBEntities context)
        {
            Model.User user = GetUser(userId, ref context);

            if (user != null)
            {
                if (user.AccessToken == accesstoken)
                {
                    return true;
                }

            }

            return false;
        }

        public static Model.User GetUser(int userId,ref Model.HangoutDBEntities context)
        {
            Model.User user = context.Users.Where(o => o.UserID == userId).SingleOrDefault();
            return user;
        }

        public static Model.User GetUser(long facebookId, ref Model.HangoutDBEntities context)
        {
            Model.User user = context.Users.Where(o => o.FacebookUserID == facebookId).SingleOrDefault();
            return user;
        }

        public static UserData GetUserData(int userId, ref Model.HangoutDBEntities context)
        {
            UserData data = new UserData();
            data.User = GetUser((int)userId, ref context);
            data.Profile = GetUserProfile(userId, context);
            return data;
        }

        public static void UpdateUserData(UserData userData,ref Model.HangoutDBEntities context)
        {
            UpdateUserProfile(userData.Profile, ref context);
        }

        public static void UpdateUser(Model.User user,ref Model.HangoutDBEntities context)
        {
            if (user.UserID != 0)
            {
                Model.User u = GetUser(user.UserID, ref context);
                
                //copy all the properties except id :)
                u.AccessToken = user.AccessToken;
                u.Activated = user.Activated;
                u.Blocked = user.Blocked;
                u.DateTimeStamp = user.DateTimeStamp;
                u.DateTimeUpdated = DateTime.Now;
                u.Email = user.Email;
                u.Expires = user.Expires;
                u.FacebookUserID = user.FacebookUserID;
                u.Locale = user.Locale;
                u.RoleID = user.RoleID;
                u.SessionKey = user.SessionKey;
                u.Username = user.Username;
                
               
                context.SaveChanges();
            }
        }

        public static void UpdateUserProfile(Model.UserProfile profile,ref Model.HangoutDBEntities context)
        {
            if (profile.UserID != 0)
            {
                Model.UserProfile u = GetUserProfile(profile.UserID,context);
                
                //copy profile :)
                if (profile.Birthday.HasValue)
                {
                    u.Age = DateTime.Now.Year - profile.Birthday.Value.Year;
                }
                else if (profile.Age.HasValue)
                {
                    u.Age = profile.Age.Value;
                }
                u.Bio = profile.Bio;
                u.Birthday = profile.Birthday;
                u.DateTimeUpdated = DateTime.Now;
                u.FirstName = profile.FirstName;
                u.LastName = profile.LastName;
                u.Gender = profile.Gender;
                u.Link = profile.Link;
                u.Name = profile.Name;
                u.Phone = profile.Phone;
                u.ProfilePicURL = profile.ProfilePicURL;
                u.RelationshipStatus = profile.RelationshipStatus;
                u.Timezone = profile.Timezone;
                u.DefaultLengthUnits = profile.DefaultLengthUnits;
                context.SaveChanges();
            }
        }

        public static List<UserData> GetUserData(List<int> userIds,ref Model.HangoutDBEntities context)
        {
            List<UserData> data = new List<UserData>();

            foreach (int id in userIds)
            {
                data.Add(GetUserData(id,ref context));
            }

            return data;
        }

        public static bool IsValid(string accesstoken,Model.HangoutDBEntities context)
        {
            if (context.Users.Where(o => o.AccessToken == accesstoken).Count() > 0)
            {
                return true;
            }
            return false;
        }

        public static bool IsValid(int userId,string accesstoken, Model.HangoutDBEntities context)
        {
            if (context.Users.Where(o =>o.UserID==userId && o.AccessToken == accesstoken).Count() > 0)
            {
                return true;
            }
            return false;
        }


        

       

    }
}